package br.ufrj.dcc.recinfo.bullsearch.lucene;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.document.NumericField;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.Version;

public class LuceneIndexer {

	private static final String dataPath = "machado_de_assis/Romances";
	private static final String indexPath = "index";
	private FSDirectory indexDir;
	private IndexWriter writer;
	
	public int start() throws CorruptIndexException, LockObtainFailedException, IOException{
		int numIndex;
		indexDir = FSDirectory.open(new File(indexPath));
		
		// Analyzers
		Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_33);

		IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_33, analyzer);
		// Cria novo índice no diretório
		// Adiciona novos documentos a um índice existente
		iwc.setOpenMode(OpenMode.CREATE_OR_APPEND);
  	
		// Cria/abre índice
		writer = new IndexWriter(indexDir, iwc);
		
		IndexDirectory(new File(dataPath));
		
		numIndex = writer.numDocs();
		writer.optimize();
		writer.close();
		
		System.out.println("Número de indices: "+numIndex);
		
		return numIndex;
		
	}
	
	private void IndexDirectory(File dir) throws IOException{
		
		String [] files = dir.list();
		
		for(String fileName: files){
			
			File file = new File(dataPath + "//" + fileName);
			
			if(file.isHidden() || !file.exists() || !file.canRead())
				continue;
			
			if(file.isDirectory()){
				IndexDirectory(file);
			} else{
				IndexFile(file);
			}
		}
	}
	
	private void IndexFile(File file) throws CorruptIndexException, IOException{
		Document doc = new Document();
		// Campo armazenado, indexado, não analisado 
		Field pathField = new Field("path", file.getPath(), Field.Store.YES, Field.Index.NOT_ANALYZED);
		doc.add(pathField);
		

		// Campo armazenado, indexado e analisado como número 
        NumericField modifiedField = new NumericField("modified", Field.Store.YES, true);
        modifiedField.setLongValue(file.lastModified());
        doc.add(modifiedField);

        
		// Campo não armazenado, indexado e analisado como número 
        NumericField lengthField = new NumericField("length");
        lengthField.setLongValue(file.length());
        doc.add(lengthField);


        // Campo não armazenado, indexado, analisado
        Field contentsField = new Field("contents", new FileReader(file));
        doc.add(contentsField);
        
        
        // Indexa documento
		if (writer.getConfig().getOpenMode() == OpenMode.CREATE) {
			System.out.println("Adicionando " + file);
			writer.addDocument(doc);
		} else {
			System.out.println("Atualizando " + file);
			writer.updateDocument(new Term("path", file.getPath()), doc);
		}

	}
}
